vlwkaos' digital garden

Typescript웹 프로젝트 Webpack Sentry 연동하기

Sentry는 로그 수집용 소프트웨어다. 서버만 있다면 오픈소스 버전을 직접 호스팅하여 사용할 수 있다. 웹 프론트에 관한 글이므로 Sentry를 자체 호스팅하고 있다고 가정하겠다.

목표

Webpack과 TypeScript를 사용하는 웹 프론트엔드 프로젝트에 Sentry를 설치하고 소스맵을 업로드 하여 에러 로그를 수집하고 코드를 분석할 수 있다.

방법 (2020-11-19)

Sentry 웹에 접속한 뒤 상단 좌측 드롭 메뉴에서 API > API 토큰을 생성하여 준비한다. 토큰은 계정당 하나로 고유하다. 토큰 권한은 적어도 다음을 포함해야한다.

  • project:read
  • project:releases
  • project:write
  • org:read

API 토큰은 계정이 삭제되면 사라진다. 한 유저의 토큰값을 쓰다가 그 사람이 나가서 계정을 삭제한 경우 다른 사람의 API 토큰 값을 설정에 넣어주면 된다

SentryWebpackPlugin 설치

Sentry 웹팩 플러그인을 개발용 노드 모듈로 추가한다. 이 플러그인은 웹팩에서 sentry-cli의 기능을 실행하도록 도와준다.

npm i -D @sentry/webpack-plugin

웹팩 환경설정 파일에 다음을 추가한다.

// ... 다른 모듈 불러오기
const SentryWebpackPlugin = require("@sentry/webpack-plugin");

// 릴리즈에 사용할 이름을 만들어 준다: 버전@git해쉬값, 해당 값은 EnvironmentPlugin등을 이용해서 브라우저 코드에서 활용한다.
const commitHash = require("child_process").execSync("git rev-parse HEAD").toString(); 
const sentryReleaseString = `${version}@${commitHash}`; // 버전은 알아서 지정

module.exports = {
    // ... 
    plugins: [
      //...
       // production용 sentry plugin 추가    
       new SentryWebpackPlugin({
           authToken: "토큰값",
           url: "센트리 호스팅하는 URL",
           org: "기관명",
           project: "프로젝트명",
           release: sentryReleaseString,
           include: "build", // 소스맵이 포함된 폴더
       });
    ]
}

브라우저 개발자 도구에 소스맵이 필요한 것 처럼, 센트리가 수집한 에러 지점을 타입스크립트 원본 소스로 보여지게 하려면 소스맵이 필요하다. SentryWebpackPlugin이 소스맵의 업로드를 도와준다. 빌드시 소스맵이 생성되도록 한다.

추가로 tsconfig.json에 다음을 추가해야한다.

    "compilerOptions": {
      "sourceMap": true
      "inlineSources": true // typescript는 소스맵에 소스가 포함되어야함
    }

그러나 inlineSources 옵션은 개발시 빌드를 느리게 하기 때문에 다음처럼 프로덕션 전용 설정파일을 분리하여 옵션을 주는게 좋다.

{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "inlineSources": true
    }
}

다른 tsconfig을 빌드시에 지정하려면 방법이 세가지 있다.

  1. ts-loader를 쓰는경우 직접 지정할 수 있다. (분기를 두면 된다)
  2. 다른 loader를 쓰는 경우
    1. shell command로 빌드 전에 파일을 바꿔치기 하기.
      • 이 경우에는 위처럼 extends하는 형태가 아닌 전체 config파일이어야한다.
    2. tsc -p tsconfig.production.json && webpack
      • 이 경우 compiler가 한번 돌아야하므로 빌드가 느려진다.

브라우저용 Sentry 클라이언트 설치

npm i --save @sentry/browser @sentry/tracing 로 설치한다.

브라우저 코드에서 초기 시점에 다음을 호출하여 센트리를 초기화한다.

 Sentry.init({
     dsn: 'DSN URL이 들어가는 자리',
     release: process.env.SENTRY_RELEASE, // 빌드환경에서 만든 고유 ID (버전@hash)
     integrations: [new Integrations.BrowserTracing()], // 브라우저 에러 캡쳐 활성화.
     maxBreadcrumbs: 70, // 스택수
     sampleRate: 0.05, // 전체 로그 수집율 1.0이면 100% 수집
     tracesSampleRate: 0.05, // 트레이스 수집율 1.0이면 100% 수집
     debug: true // 디버깅용 옵션 프로덕션에서는 false
 });

센트리가 초기화 됐다면 다음과 같이 로그를 보내볼 수 있다.

Sentry.captureMessage('Hello World');

이제 소스맵 업로드가 제대로 됐는지 확인하기 위해 일부러 로그를 수집해보자.

로그 trace가 다음처럼 가독이 가능한 형태로 뜨면 소스맵이 제대로 적용된 것이다.

에러 발생위치

업로드 후 소스맵 삭제하기

프로덕션에 소스맵을 포함하는 것은 좋지 않기 때문에 삭제를 해주어야한다.

소스맵 삭제는 두 단계가 필요한데, *.map.js 파일을 삭제하는 것과 *.js파일내 끝에 붙어있는 //# sourceMapURL....\ 이 부분을 삭제해 줘야한다.

처음에 스크립트를 돌리는 플러그인을 만들어서 다음과 같이 처리하려 했는데, 빌드 환경이 달라지면 스크립트도 달라져야하므로 관리할게 많아진다.

대신 다음 플러그인을 사용하였다.

https://www.npmjs.com/package/delete-sourcemap-webpack-plugin

const DeleteSourceMapPlugin = require('delete-sourcemap-webpack-plugin');

module.exports = {
    plugins: [
        // ...
        new DeleteSourceMapPlugin()
    ]
}

빌드 후 소스맵이 제대로 삭제되었는지 확인해주자.

Referred in

Typescript웹 프로젝트 Webpack Sentry 연동하기